/**
 * A wheel joint. This joint provides two degrees of freedom: translation
 * along an axis fixed in bodyA and rotation in the plane. You can use a
 * joint limit to restrict the range of motion and a joint motor to drive
 * the rotation or to model rotational friction.
 * This joint is designed for vehicle suspensions.
**/
public class b2WheelJoint extends b2Joint {

	public b2WheelJoint(int addr) {
		super(addr);
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			super.release();
		}
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorA() {
		return new b2Vec2(jniGetAnchorA(address));
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorB() {
		return new b2Vec2(jniGetAnchorB(address));
	}

	/// Get the reaction force given the inverse time step.
	/// Unit is N.
	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jniGetReactionForce(address));
	}

	/// Get the reaction torque due to the joint limit given the inverse time step.
	/// Unit is N*m.
	public float GetReactionTorque(float inv_dt) {
		return jniGetReactionTorque(address, inv_dt);
	}

	/// The local anchor point relative to bodyA's origin.
	public b2Vec2 GetLocalAnchorA() {
		return new b2Vec2(jniGetLocalAnchorA(address));
	}

	/// The local anchor point relative to bodyB's origin.
	public b2Vec2 GetLocalAnchorB() {
		return new b2Vec2(jniGetLocalAnchorB(address));
	}

	/// The local joint axis relative to bodyA.
	public b2Vec2 GetLocalAxisA() {
		return new b2Vec2(jniGetLocalAxisA(address));
	}

	/// Get the current joint translation, usually in meters.
	public float GetJointTranslation() {
		return jniGetJointTranslation(address);
	}

	/// Get the current joint translation speed, usually in meters per second.
	public float GetJointSpeed() {
		return jniGetJointSpeed(address);
	}

	/// Is the joint motor enabled?
	public boolean IsMotorEnabled() {
		return jniIsMotorEnabled(address);
	}

	/// Enable/disable the joint motor.
	public void EnableMotor(boolean flag) {
		jniEnableMotor(address, flag);
	}

	/// Set the motor speed, usually in radians per second.
	public void SetMotorSpeed(float speed) {
		jniSetMotorSpeed(address, speed);
	}

	/// Get the motor speed, usually in radians per second.
	public float GetMotorSpeed() {
		return jniGetMotorSpeed(address);
	}

	/// Set/Get the maximum motor force, usually in N-m.
	public void SetMaxMotorTorque(float torque) {
		jniSetMaxMotorTorque(address, torque);
	}

	public float GetMaxMotorTorque() {
		return jniGetMaxMotorTorque(address);
	}

	/// Get the current motor torque given the inverse time step, usually in N-m.
	public float GetMotorTorque(float inv_dt) {
		return jniGetMotorTorque(address, inv_dt);
	}

	/// Set/Get the spring frequency in hertz. Setting the frequency to zero disables the spring.
	public void SetSpringFrequencyHz(float hz) {
		jniSetSpringFrequencyHz(address, hz);
	}

	public float GetSpringFrequencyHz() {
		return jniGetSpringFrequencyHz(address);
	}

	/// Set/Get the spring damping ratio
	public void SetSpringDampingRatio(float ratio) {
		jniSetSpringDampingRatio(address, ratio);
	}

	public float GetSpringDampingRatio() {
		return jniGetSpringDampingRatio(address);
	}

	/**Dump to b2Log.(not implemented yet)*/
	public void Dump() {
		throw new UnsupportedOperationException();
	}

	private static native float jniGetSpringDampingRatio(int me);
	private static native void jniSetSpringDampingRatio(int me, float ratio);
	private static native float jniGetSpringFrequencyHz(int me);
	private static native void jniSetSpringFrequencyHz(int me, float hz);
	private static native float jniGetMotorTorque(int me, float inv_dt);
	private static native float jniGetMaxMotorTorque(int me);
	private static native void jniSetMaxMotorTorque(int me, float torque);
	private static native float jniGetMotorSpeed(int me);
	private static native void jniSetMotorSpeed(int me, float speed);
	private static native void jniEnableMotor(int me, boolean flag);
	private static native boolean jniIsMotorEnabled(int me);
	private static native float jniGetJointSpeed(int me);
	private static native float jniGetJointTranslation(int me);
	private static native int jniGetLocalAxisA(int me);
	private static native int jniGetLocalAnchorA(int me);
	private static native int jniGetLocalAnchorB(int me);
	private static native float jniGetReactionTorque(int me, float inv_dt);
	private static native int jniGetReactionForce(int me);
	private static native int jniGetAnchorA(int me);
	private static native int jniGetAnchorB(int me);
}
